package com.qfedu.service.impl;

import com.github.wxpay.sdk.WXPay;
import com.qfedu.ProductAPI;
import com.qfedu.config.MyWxPayConfig;
import com.qfedu.entity.Orders;
import com.qfedu.entity.ResultVo;
import com.qfedu.entity.SkuDate;
import com.qfedu.entity.UserHobby;
import com.qfedu.mapper.OrderItemMapper;
import com.qfedu.mapper.OrderMapper;
import com.qfedu.mapper.SkuDateMapper;
import com.qfedu.recommend.RecommendAPI;
import com.qfedu.service.OrderService;
import com.qfedu.util.IdWorker;
import com.qfedu.vo.TokenVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 作者：刘随阳
 * 时间: 2021/9/22 17:31
 * 描述：神光照耀,太白成瑞。六丙来迎,百福悠归
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ProductAPI productAPI;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private SkuDateMapper skuDateMapper;
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RecommendAPI recommendAPI;

    @Override
    public ResultVo getOrderToken() {
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        stringRedisTemplate.boundValueOps(uuid).set("123456",30, TimeUnit.MINUTES);
        return ResultVo.success("生成成功",uuid);
    }

    @Override
    public ResultVo reserve(Integer productId, Integer skuId, Integer dateId) {
        ResultVo orderParams = productAPI.getOrderParams(productId, skuId, dateId);
        return orderParams;
    }

    @Override
    public ResultVo saveOrder(Orders orders, TokenVo tokenVo) {
        //保证接口幂等性问题
        if (!stringRedisTemplate.delete(tokenVo.getOrderToken())){
            return ResultVo.fail("订单已经生成");
        }

        //获取锁对象
        RLock lock = redissonClient.getLock(orders.getOrderDateId().toString());
        boolean b = false;

        try {
            //尝试加锁
            b = lock.tryLock(3, TimeUnit.SECONDS);
            if(b){
                //如果加锁成功，则执行业务
//                System.out.println("1.查询库存");
//                System.out.println("2.保存订单");
//                System.out.println("3.生成快照");
//                System.out.println("4.扣减库存");
//                System.out.println("5.删除购物车");
                Integer orderDateId = orders.getOrderDateId();
                SkuDate skuDate = skuDateMapper.selectByPrimaryKey(orderDateId);
                Integer dateStock = skuDate.getDateStock();
                if(dateStock <
                        orders.getOrderCount()){
                    return ResultVo.fail("库存不足");
                }
                skuDate.setDateStock(skuDate.getDateStock()- orders.getOrderCount());
                int i = skuDateMapper.updateByPrimaryKey(skuDate);

                JwtParser parser = Jwts.parser();
                parser.setSigningKey("123456");
                Jws<Claims> claimsJws = parser.parseClaimsJws(tokenVo.getToken());
                Claims body = claimsJws.getBody();
                String id = body.getId();
                Integer productId = skuDateMapper.getProductId(orders.getOrderDateId());
                recommendAPI.updateUserHobby(new UserHobby(null,Integer.parseInt(id),productId,3));
                orders.setOrderUserId(Integer.parseInt(id));
                orders.setOrderStatus(1);
                orders.setOrderCreateDate(new Date());
                IdWorker idWorker = new IdWorker(1,1,1);
                long l = idWorker.nextId();
                String orderId = Long.toString(l);
                orders.setOrderId(orderId);
                orderMapper.insert(orders);
//        orderItem.setOrderId(UUID.randomUUID().toString().replaceAll("-",""));
//        orderItemMapper.insert(orderItem);
                amqpTemplate.convertAndSend("ex","c",Long.toString(l));
                System.out.println("订单号：" + orderId);
                lock.unlock();
                return ResultVo.success("订单生成成功",orderId);
            }else{
                return ResultVo.fail("订单提交超时，请重试！");
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ResultVo.fail("订单提交失败，请重试！");
    }

    @Override
    public ResultVo selectOrder(String orderId) {
        Orders orders = orderMapper.selectByPrimaryKey(orderId);
        if(StringUtils.isEmpty(orders)){
            return ResultVo.fail("查询失败,订单不存在");
        }

        return ResultVo.success("查询成功",orders);
    }

    @Override
    public ResultVo getPay(String orderId) {
        Orders orders = orderMapper.selectByPrimaryKey(orderId);
        if(orders == null) {
            return ResultVo.fail("订单不存在");
        }
        if (orders.getOrderStatus() != 1){
            return ResultVo.fail("订单已经支付或已取消");
        }

        Integer productId = skuDateMapper.getProductId(orders.getOrderDateId());
        recommendAPI.updateUserHobby(new UserHobby(null,orders.getOrderUserId(),productId,4));


        try {
            WXPay wxPay = new WXPay(new MyWxPayConfig());
            HashMap<String, String> data = new HashMap<>();
            data.put("out_trade_no",orders.getOrderId());        //订单号
            data.put("body",orders.getOrderProductName());               //订单描述
            data.put("total_fee","1");                          //付款金额 始终设置为1分
            data.put("trade_type","NATIVE");                    //交易类型
            data.put("fee_type","CNY");                         //币种   CNY 人民币
            data.put("notify_url","http://mememe.free.idcfengye.com/wx/callback");             //回调方法
            Map<String, String> resp = wxPay.unifiedOrder(data);
            String payUrl = resp.get("code_url");
            HashMap<String, String> params = new HashMap<>();
            params.put("payUrl",payUrl);
            params.put("orderId",orders.getOrderId());
            params.put("orderPrice",orders.getOrderPrice().toString());
            return ResultVo.success("订单提交成功",params);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return ResultVo.fail("订单提交失败！");
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVo.fail("订单提交失败！");
        }
    }

    @Override
    public boolean updateOrder(String orderId) {
        Orders orders = orderMapper.selectByPrimaryKey(orderId);
        if(orders == null){
            return false;
        }
        orders.setOrderStatus(2);
        orderMapper.updateByPrimaryKey(orders);
        return true;
    }

}
